package ch.unisi.inf.editor;
import ch.unisi.inf.engine.Image;

import java.awt.*;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;

import javax.swing.*;


import java.io.*;
import java.util.ArrayList;

/**
 * @author matthias.eberli@lu.unisi.ch
 */
public class ImagePanel extends JComponent {
    
    private int width;
    private int height;
    
    private final ArrayList<ImagePanelListener> listeners;
    private static JFileChooser fileChooser = new JFileChooser(System.getProperty("/Users"));

    private Image panelImage;

    
    public ImagePanel()
    {
        width = 640;
        height = 480;
        listeners = new ArrayList<ImagePanelListener>();
        panelImage = null;
    }

    /**
     * sets an image to the panel
     */
    public void setImage(Image image)
    {
        if(image != null) {
            width = image.getWidth();
            height = image.getHeight();
            panelImage = image;
            repaint();
        }
    }
    
    /**
     * Clear the image on this panel.
     */
    public void clearImage()
    {
        if(panelImage != null) {
            Graphics imageGraphics = panelImage.getGraphics();
            imageGraphics.setColor(Color.LIGHT_GRAY);
            imageGraphics.fillRect(0, 0, width, height);
            repaint();
        }
    }
    
    /**
     * checks if the panel has an image loaded
     */
    public boolean hasImage()
    {
        if(panelImage == null)
            return false;
        return true;
    }
    
    /**
     * opens a file chooser to select where to save a file
     */
    public void saveAs()
    {
        if(panelImage != null) {
            int returnVal = fileChooser.showSaveDialog(this);
    
            if(returnVal != JFileChooser.APPROVE_OPTION) {
                return;  // cancelled
            }
            File selectedFile = fileChooser.getSelectedFile();
            panelImage.save(selectedFile);
        }
    }
    
    /**
     * Apply a given filter to the current image.
     * @param filter The filter to be applied.
     */
    public void applyFilter(Filter filter)
    {
        if(panelImage != null) {
            filter.apply(panelImage);
            this.repaint();
        }
    }

    /**
     * returns the preferred size of the panel
     */
    public Dimension getPreferredSize()
    {
        return new Dimension(width, height);
    }
    
    /**
     *  overwrites the paintComponent for this component
     *  
     */
    public void paintComponent(Graphics g)
    {
        Dimension size = getSize();
        g.clearRect(0, 0, size.width, size.height);
        if(panelImage != null) {
            g.drawImage(panelImage, 0, 0, null);
        }
    }
    
    //--- listener management
    public void addImagePanelListener(final ImagePanelListener li) {
        listeners.add(li);
    }
    
    public void removeImagePanelListener(final ImagePanelListener li) {
        listeners.remove(li);
    }
    
    private final void fireImageCharged() {
        for (final ImagePanelListener li : listeners) {
            li.imageCharged();
        }
    }

}